<template>
  <div class="fileTree">
    <dashed-line-tree ref="fileTree" :data="treeData" :props="props" :expand-on-click-node="false"
      :default-expand-all="false" @node-click="handleNodeClick">
      <template #default="{ node, data }">
        <div class="tree-info">
          <span
            :class="data.nodeVisible ? 'ico_loading' : (data.is_dir ? (node.expanded ? 'ico_open' : 'ico_close') : 'ico_file')"
            class="spanButton" />
          <span class="text" :title="node.label">{{ node.label }}</span>
          <span class="custom-tree-node">
            <span class="size" :class="{ sizeRight: dropdownList.length === 0 }">{{ data.fileSize }}</span>
            <el-dropdown v-if="dropdownList.length" trigger="click"
              @command="(command) => treeButtonHandleCommand(command, data, node)">
              <el-button type="text" icon="el-icon-more" class="node-button" @click.stop="" />
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item v-for="dro in dropdownList" v-show="dro.view(data)" :key="dro.command"
                    :command="dro.command">{{ dro.labelHandle ? dro.labelHandle(data) : dro.label }}</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </span>
        </div>
      </template>
    </dashed-line-tree>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, ref } from 'vue'
import { bytesToSize, download, urlIdHandle } from 'src/utils/designerTool/toole'
import { isUndefined } from 'src/utils/designerTool/validate'
import { ElMessage } from 'element-plus'
// import DashedLineTree from '@/components/tree/tree'
const props = defineProps({
  idConfig: {
    type: Object,
    default: () => {
      return {}
    }
  },
  storageType: {
    type: String,
    default: ''
  }
})
const treeData = ref([{
  label: '/',
  path: '/',
  nodeVisible: false,
  is_dir: true,
  dataState: false,
  children: []
}])
const propsRef = ref({
  label: 'label',
  children: 'children'
})
const dispatchEventClick = ref(true)
const treeVisible = ref(false)
const contextmenuData = ref({
  type: '',
  data: '',
  node: ''
})
const fileTree=ref(null)
const dropdownList = computed(() => {
  return [
    {
      label: '刷新',
      command: 'open',
      view: (data: any) => data.is_dir
    },
    {
      label: '下载',
      command: 'download',
      view: (data: any) => !data.is_dir
    }
  ]
})

function init() {
  if (dispatchEventClick.value) {
    nextTick(() => {
      fileTree.value.$children[0].$el.dispatchEvent(new MouseEvent('click'))
      dispatchEventClick.value = false
    })
  }
}
function handleNodeClick(data:any, node:any, self:any) {
  if (!((props.idConfig.workflowInfoId && props.idConfig.instanceId) || props.idConfig.experiment_id || props.idConfig.dataSetId)) {
    return
  }
  if (node.click === undefined || node.click === false) {
    if (data.is_dir) {
      if (!node.expanded) {
        if (!treeVisible.value) {
          if (data.dataState) {
            node.expanded = true
            return
          }
          data.nodeVisible = true
          treeVisible.value = true
          let url = ''
          if (props.idConfig.workflowInfoId && props.idConfig.instanceId) {
            url = this.$api.getWorkflowInstancesStorages(props.idConfig.workflowInfoId, props.idConfig.instanceId, {
              operator_id: props.idConfig.operator_id,
              node_id: props.idConfig.node_id,
              storage_type: props.storageType,
              path: data.path === '/' ? undefined : data.path
            })
          } else if (props.idConfig.experiment_id) {
            url = this.$api.getOperatorExperimentsStorages(props.idConfig.experiment_id, {
              path: data.path === '/' ? undefined : data.path,
              storage_type: props.storageType
            })
          }
          url.then((res:any) => {
            const children = res.result.map((val:any) => {
              // 用来兼容ai和flow两种写法
              if (isUndefined(val.is_dir)) {
                val['is_dir'] = isUndefined(val.isDir) ? false : val.isDir
              }
              val.label = val.name || val.path
              val.path = (props.idConfig.dataSetId ? '' : (data.path === '/' ? data.path : (data.path + '/'))) + val.path
              if (val.file_size) {
                val.fileSize = bytesToSize(val.file_size)
              } else if (val.fileSize) {
                val.fileSize = bytesToSize(val.fileSize)
              }
              val['nodeVisible'] = false
              val['dataState'] = false
              val['children'] = []
              return val
            })
            children.sort((a, b) => {
              return a.is_dir ? -1 : 1
            })
            data.dataState = true
            data.children = children
            node.expanded = true
          }, res => {
            data.dataState = false
            this.$layer_message(res.result)
          }).finally(() => {
            data.nodeVisible = false
            treeVisible.value = false
          })
        }
      } else {
        node.expanded = false
      }
    } else {
      this.$emit('addTab', data, node.data.path)
    }
  }
  node.click = false
}
function treeButtonHandleCommand(type, data, node) {
  contextmenuData.value.type = type
  contextmenuData.value.data = data
  contextmenuData.value.node = node
  switch (type) {
    case 'open': {
      refreshNodeData()
      break
    }
    case 'download':
      if (data.is_dir) {
        ElMessage.error('文件夹无法下载!')
      } else {
        downloadFile(node, data)
      }
      break
    default:
  }
}
// 1刷新当前节点,2刷新父级
function refreshNodeData(type = 1) {
  let data = contextmenuData.value.data
  if (data.path === '/') {
    type = 1
  }
  let node = contextmenuData.value.node
  if (type === 2) {
    node = node.parent
    data = node.data
  }
  node.click = false
  node.expanded = false
  data.dataState = false
  handleNodeClick(data, node)
}
function downloadFile(node, data) {
  data.nodeVisible = true
  node['click'] = true
  let url = ''
  if (props.idConfig.workflowInfoId && props.idConfig.instanceId) {
    url = this.$api.getWorkflowInstancesStorages(props.idConfig.workflowInfoId, props.idConfig.instanceId, {
      path: data.path,
      is_dir: 0,
      operator_id: props.idConfig.operator_id,
      node_id: props.idConfig.node_id,
      storage_type: props.storageType
    })
  } else if (props.idConfig.experiment_id) {
    url = this.$api.getOperatorExperimentsStorages(props.idConfig.experiment_id, {
      path: data.path,
      is_dir: 0,
      storage_type: props.storageType
    })
  } else if (props.idConfig.dataSetId) {
    url = '/api/data/dataset/' + props.idConfig.dataSetId + '/file/download'
    download(urlIdHandle(url + '?path=' + data.path))
    setTimeout(() => {
      data.nodeVisible = false
    }, 1000)
    return
  } else {
    data.nodeVisible = false
    return
  }
  url.then(res => {
    this.$api.getSystemUploadFile({
      url: res.result.url
    }).then(res => {
      download(res.result.url, data.label)
    }, res => {
      ElMessage(res.result)
    }).finally(() => {
      data.nodeVisible = false
    })
  }, res => {
    ElMessage(res.result)
    data.nodeVisible = false
  })
}


</script>

<style lang="scss" scoped>
@import '~@/views/canvas/RunContainer/fileTree.scss';
</style>
